home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / shell / cdialog-.9a / cdialog- / cdialog-0.9a / util.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-15  |  18.3 KB  |  721 lines

  1. /*
  2.  *  util.c
  3.  *
  4.  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  5.  *
  6.  *  This program is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU General Public License
  8.  *  as published by the Free Software Foundation; either version 2
  9.  *  of the License, or (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include "dialog.h"
  22.  
  23. #ifdef HAVE_NCURSES
  24. /* use colors by default? */
  25. bool use_colors = USE_COLORS;
  26. /* shadow dialog boxes by default?
  27.    Note that 'use_shadow' implies 'use_colors' */
  28. bool use_shadow = USE_SHADOW;
  29. #endif
  30.  
  31. const char *dialog_result;
  32.  
  33. /* 
  34.  * Attribute values, default is for mono display
  35.  */
  36. chtype attributes[] =
  37. {
  38.     A_NORMAL,            /* screen_attr */
  39.     A_NORMAL,            /* shadow_attr */
  40.     A_REVERSE,            /* dialog_attr */
  41.     A_REVERSE,            /* title_attr */
  42.     A_REVERSE,            /* border_attr */
  43.     A_BOLD,            /* button_active_attr */
  44.     A_DIM,            /* button_inactive_attr */
  45.     A_UNDERLINE,        /* button_key_active_attr */
  46.     A_UNDERLINE,        /* button_key_inactive_attr */
  47.     A_NORMAL,            /* button_label_active_attr */
  48.     A_NORMAL,            /* button_label_inactive_attr */
  49.     A_REVERSE,            /* inputbox_attr */
  50.     A_REVERSE,            /* inputbox_border_attr */
  51.     A_REVERSE,            /* searchbox_attr */
  52.     A_REVERSE,            /* searchbox_title_attr */
  53.     A_REVERSE,            /* searchbox_border_attr */
  54.     A_REVERSE,            /* position_indicator_attr */
  55.     A_REVERSE,            /* menubox_attr */
  56.     A_REVERSE,            /* menubox_border_attr */
  57.     A_REVERSE,            /* item_attr */
  58.     A_NORMAL,            /* item_selected_attr */
  59.     A_REVERSE,            /* tag_attr */
  60.     A_REVERSE,            /* tag_selected_attr */
  61.     A_NORMAL,            /* tag_key_attr */
  62.     A_BOLD,            /* tag_key_selected_attr */
  63.     A_REVERSE,            /* check_attr */
  64.     A_REVERSE,            /* check_selected_attr */
  65.     A_REVERSE,            /* uarrow_attr */
  66.     A_REVERSE            /* darrow_attr */
  67. };
  68.  
  69. #ifdef HAVE_NCURSES
  70. #include "colors.h"
  71.  
  72. /*
  73.  * Table of color values
  74.  */
  75. int color_table[][3] =
  76. {
  77.     {SCREEN_FG, SCREEN_BG, SCREEN_HL},
  78.     {SHADOW_FG, SHADOW_BG, SHADOW_HL},
  79.     {DIALOG_FG, DIALOG_BG, DIALOG_HL},
  80.     {TITLE_FG, TITLE_BG, TITLE_HL},
  81.     {BORDER_FG, BORDER_BG, BORDER_HL},
  82.     {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
  83.     {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
  84.     {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
  85.     {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
  86.     {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
  87.     {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
  88.      BUTTON_LABEL_INACTIVE_HL},
  89.     {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
  90.     {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
  91.     {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
  92.     {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
  93.     {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
  94.     {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
  95.     {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
  96.     {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
  97.     {ITEM_FG, ITEM_BG, ITEM_HL},
  98.     {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
  99.     {TAG_FG, TAG_BG, TAG_HL},
  100.     {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
  101.     {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
  102.     {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
  103.     {CHECK_FG, CHECK_BG, CHECK_HL},
  104.     {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
  105.     {UARROW_FG, UARROW_BG, UARROW_HL},
  106.     {DARROW_FG, DARROW_BG, DARROW_HL},
  107. };                /* color_table */
  108. #endif
  109.  
  110. /*
  111.  * Display background title if it exists ...
  112.  */
  113. void put_backtitle(void)
  114. {
  115.  
  116.   int i;
  117.  
  118.   if (backtitle != NULL)
  119.   {
  120.     wattrset(stdscr, screen_attr);
  121.     wmove(stdscr, 0, 1);
  122.     waddstr(stdscr,backtitle);
  123.     for(i=0; i<COLS-strlen(backtitle); i++)
  124.       waddch(stdscr, ' ');
  125.     wmove(stdscr, 1, 1);
  126.     for(i=0; i<COLS-2; i++)
  127.       waddch(stdscr, ACS_HLINE);
  128.   }
  129.  
  130.   wnoutrefresh(stdscr);
  131. }
  132.  
  133. /*
  134.  * Set window to attribute 'attr'
  135.  */
  136. void
  137. attr_clear (WINDOW * win, int height, int width, chtype attr)
  138. {
  139.     int i, j;
  140.  
  141.     wattrset (win, attr);
  142.     for (i = 0; i < height; i++) {
  143.     wmove (win, i, 0);
  144.     for (j = 0; j < width; j++)
  145.         waddch (win, ' ');
  146.     }
  147.     touchwin (win);
  148. }
  149.  
  150. /*
  151.  * Do some initialization for dialog
  152.  */
  153. void
  154. init_dialog (void)
  155. {
  156.     mouse_open ();
  157. #ifdef HAVE_RC_FILE
  158. #ifdef HAVE_NCURSES
  159.     if (parse_rc () == -1)    /* Read the configuration file */
  160.     exiterr("");
  161. #endif
  162. #endif
  163.  
  164.     initscr ();            /* Init curses */
  165.     keypad (stdscr, TRUE);
  166.     cbreak ();
  167.     noecho ();
  168.     screen_initialized = 1;
  169.  
  170. #ifdef HAVE_NCURSES
  171.     if (use_colors || use_shadow)    /* Set up colors */
  172.     color_setup ();
  173. #endif
  174.  
  175.     /* Set screen to screen attribute */
  176.     attr_clear (stdscr, LINES, COLS, screen_attr);
  177. }
  178.  
  179. #ifdef HAVE_NCURSES
  180. /*
  181.  * Setup for color display
  182.  */
  183. void
  184. color_setup (void)
  185. {
  186.     int i;
  187.  
  188.     if (has_colors ()) {    /* Terminal supports color? */
  189.     start_color ();
  190.  
  191.     /* Initialize color pairs */
  192.     for (i = 0; i < ATTRIBUTE_COUNT; i++)
  193.         init_pair (i + 1, color_table[i][0], color_table[i][1]);
  194.  
  195.     /* Setup color attributes */
  196.     for (i = 0; i < ATTRIBUTE_COUNT; i++)
  197.         attributes[i] = C_ATTR (color_table[i][2], i + 1);
  198.     }
  199. }
  200. #endif
  201.  
  202. /*
  203.  * End using dialog functions.
  204.  */
  205. void
  206. end_dialog (void)
  207. {
  208.     mouse_close ();
  209.     endwin ();
  210. }
  211.  
  212. /*
  213.  * Print a string of text in a window, automatically wrap around to the
  214.  * next line if the string is too long to fit on one line. Note that the
  215.  * string may contain "\n" to represent a newline character or the real
  216.  * newline '\n', but in that case, auto wrap around will be disabled.
  217.  */
  218. void print_autowrap(WINDOW *win, const char *prompt, int width, int y, int x)
  219. {
  220.   int first = 1, cur_x, cur_y;
  221.   char tempstr[MAX_LEN+1], *word, *tempptr, *tempptr1;
  222.  
  223.   strcpy(tempstr, prompt);
  224.   if ((strstr(tempstr, "\\n") != NULL) ||
  225.       (strchr(tempstr, '\n') != NULL)) {    /* Prompt contains "\n" or '\n' */
  226.     word = tempstr;
  227.     cur_y = y;
  228.     if (cr_wrap) cur_y++;
  229.     wmove(win, cur_y, x);
  230.     while (1) {
  231.       tempptr = strstr(word, "\\n");
  232.       tempptr1 = strchr(word, '\n');
  233.       if (tempptr == NULL && tempptr1 == NULL)
  234.         break;
  235.       else if (tempptr == NULL) {    /* No more "\n" */
  236.         tempptr = tempptr1;
  237.         tempptr[0] = '\0';
  238.       }
  239.       else if (tempptr1 == NULL) {    /* No more '\n' */
  240.         tempptr[0] = '\0';
  241.         tempptr++;
  242.       }
  243.       else {    /* Prompt contains both "\n" and '\n' */
  244.         if (strlen(tempptr) <= strlen(tempptr1)) {
  245.           tempptr = tempptr1;
  246.           tempptr[0] = '\0';
  247.         }
  248.         else {
  249.           tempptr[0] = '\0';
  250.           tempptr++;
  251.         }
  252.       }
  253.  
  254.       waddstr(win, word);
  255.       word = tempptr + 1;
  256.       wmove(win, ++cur_y, x);
  257.     }
  258.     waddstr(win, word);
  259.   }
  260.   else if (strlen(tempstr) <= width-x*2) {     /* If prompt is short */
  261.     cur_y=y;
  262.     if (cr_wrap) cur_y++;
  263.     wmove(win, cur_y, (width - strlen(tempstr)) / 2);
  264.     waddstr(win, tempstr);
  265.   }
  266.   else {
  267.     cur_x = x;
  268.     cur_y = y;
  269.     if (cr_wrap) cur_y++;
  270.     /* Print prompt word by word, wrap around if necessary */
  271.     while ((word = strtok(first ? tempstr : NULL, " ")) != NULL) {
  272.       if (first)    /* First iteration */
  273.         first = 0;
  274.       if (cur_x+strlen(word) > width-x) {    /* wrap around to next line */
  275.         cur_y++;
  276.         cur_x = x;
  277.       }
  278.       wmove(win, cur_y, cur_x);
  279.       waddstr(win, word);
  280.       getyx(win, cur_y, cur_x);
  281.       cur_x++;
  282.     }
  283.   }
  284.   if (cr_wrap) wmove(win, cur_y+1, x);
  285. }
  286.  
  287. /*
  288.  * if (height or width == -1) Maximize()
  289.  * if (height or width == 0)
  290.  *    if (there are \n in prompt)
  291.  *       width=MAX(longer line+n, mincols)
  292.  *       height=num.lines
  293.  *    else
  294.  *       calculate with aspect_ratio
  295.  */
  296. char *auto_size(char *prompt, int *height, int *width, int boxlines, int mincols) {
  297.   int count = 0, len = 0, street, i, first, nc = 4, nl = 3,
  298.       cur_x, text_width;
  299.   char *cr1, *cr2, *ptr = prompt, *str, *word;
  300.  
  301.   if ((*height == -1) || (*width == -1)) {
  302.     *height=SLINES-(begin_set ? begin_y : 0);
  303.     *width=SCOLS-(begin_set ? begin_x : 0);
  304.   }
  305.   if ((*height != 0) && (*width != 0))
  306.     return prompt;
  307.  
  308.   cr1=strstr(ptr, "\\n");
  309.   cr2=strchr(ptr, '\n');
  310.  
  311.   while ((cr1 != NULL) || (cr2 != NULL)) {  /* how many ("\n" or '\n') prompt contains? */
  312.  
  313.     if (cr1 == NULL)
  314.       street=2;
  315.     else if (cr2 == NULL)
  316.       street=1;
  317.     else if (cr1 < cr2)
  318.       street=1;
  319.     else
  320.       street=2;
  321.  
  322.     if (street == 1) {
  323.       if ((cr1-ptr) > len)
  324.         len=cr1-ptr;
  325.       ptr=cr1+2;
  326.     } else {
  327.       if ((cr2-ptr) > len)
  328.         len=cr2-ptr;
  329.       ptr=cr2+1;
  330.     }
  331.  
  332.     cr1=strstr(ptr, "\\n");
  333.     cr2=strchr(ptr, '\n');
  334.  
  335.     count++;
  336.   }
  337.  
  338.   if (strlen(ptr) > len)
  339.     len=strlen(ptr);
  340.  
  341.   /* now 'count' has the number of lines of text and 'len' the max lenght */
  342.  
  343.   if (count > 0) {  /* there are any '\n' or "\\n" */
  344.     *height=count+nl+boxlines+(cr_wrap ? 2 : 0);
  345.     *width=MAX((len+nc), mincols);
  346.     return prompt;
  347.   } else {          /* all chars in only a line */
  348.     str = (char *)malloc(strlen(prompt)*2);
  349.     text_width = MAX( ((int) sqrt((double)(aspect_ratio*strlen(prompt)))), (mincols-nc));
  350.     ptr = (char *)malloc(strlen(prompt)+1);
  351.  
  352.     while (1) {
  353.       i = 0;
  354.  
  355.       first = 1;
  356.       cur_x = 0;
  357.  
  358.       *width=text_width+nc;
  359.  
  360.       count=0;
  361.       strcpy(ptr, prompt);
  362.       while (((word=strtok(first ? ptr : NULL, " ")) != NULL) && (strlen(word) <= text_width)) {
  363.         if (first)
  364.           first = 0;
  365.  
  366.         if ((cur_x+strlen(word)) > text_width) {
  367.           count++;
  368.           cur_x=0;
  369.           str[i++]='\n';
  370.         } else if (cur_x > 0)
  371.           str[i++]=' ';
  372.  
  373.         strcpy(str+i, word);
  374.         i+=strlen(word);
  375.  
  376.         cur_x+=strlen(word)+1;
  377.       }
  378.  
  379.       if (word == NULL) break;
  380.       if (strlen(word) > text_width)
  381.         text_width = strlen(word); /* strlen(word) is surely > (mincols-nc) */
  382.       else
  383.         break;
  384.     }
  385.     str[i]=0;
  386.  
  387.     *height=count+nl+boxlines+(cr_wrap ? 2 : 0);
  388.  /* *height=(strlen(prompt)/text_width)+nl+boxlines */
  389.  
  390.     return str;
  391.   }
  392. }
  393. /* End of auto_size() */
  394.  
  395. /*
  396.  * if (height or width == -1) Maximize()
  397.  * if (height or width == 0)
  398.  *    height=MIN(SLINES, num.lines in fd+n);
  399.  *    width=MIN(SCOLS, MAX(longer line+n, mincols));
  400.  */
  401. void auto_sizefile(const char *file, int *height, int *width, int boxlines, int mincols) {
  402.   int count = 0, len = 0, nc = 4, nl = 2;
  403.   long offset;
  404.   char ch;
  405.   FILE *fd;
  406.  
  407.   /* Open input file for reading */
  408.   if ((fd = fopen(file, "rb")) == NULL)
  409.     exiterr("\nCan't open input file in auto_sizefile().\n");
  410.  
  411.   if ((*height == -1) || (*width == -1)) {
  412.     *height=SLINES-(begin_set ? begin_y : 0);
  413.     *width=SCOLS-(begin_set ? begin_x : 0);
  414.   }
  415.   if ((*height != 0) && (*width != 0)) {
  416.     fclose(fd);
  417.     return;
  418.   }
  419.  
  420.   while (!feof(fd)) {
  421.     offset = 0;
  422.     while (((ch=getc(fd)) != '\n') && !feof(fd))
  423.       if ((ch == TAB) && (tab_correct))
  424.         offset+=tab_len-(offset%tab_len);
  425.       else
  426.         offset++;
  427.  
  428.     if (offset > len)
  429.       len=offset;
  430.  
  431.     count++;
  432.   }
  433.  
  434.   /* now 'count' has the number of lines of fd and 'len' the max lenght */
  435.  
  436.   *height=MIN(SLINES, count+nl+boxlines);
  437.   *width=MIN(SCOLS, MAX((len+nc), mincols));
  438.   /* here width and height can be maximized if > SCOLS|SLINES because
  439.      textbox-like widgets don't put all <file> on the screen.
  440.      Msgbox-like widget instead have to put all <text> correctly. */
  441.  
  442.   fclose(fd);
  443. }
  444. /* End of auto_sizefile() */
  445.  
  446. /*
  447.  * Print a button
  448.  */
  449. void
  450. print_button (WINDOW * win, const char *label, int y, int x, int selected)
  451. {
  452.     int i, temp;
  453.  
  454.     wmove (win, y, x);
  455.     wattrset (win, selected ? button_active_attr : button_inactive_attr);
  456.     waddstr (win, "<");
  457.     temp = strspn (label, " ");
  458.     mouse_mkbutton (y, x, strlen (label) + 2, tolower (label[temp]));
  459.     label += temp;
  460.     wattrset (win, selected ? button_label_active_attr
  461.           : button_label_inactive_attr);
  462.     for (i = 0; i < temp; i++)
  463.     waddch (win, ' ');
  464.     wattrset (win, selected ? button_key_active_attr
  465.           : button_key_inactive_attr);
  466.     waddch (win, label[0]);
  467.     wattrset (win, selected ? button_label_active_attr
  468.           : button_label_inactive_attr);
  469.     waddstr (win, label + 1);
  470.     wattrset (win, selected ? button_active_attr : button_inactive_attr);
  471.     waddstr (win, ">");
  472.     wmove (win, y, x + temp + 1);
  473. }
  474.  
  475. /*
  476.  * Draw a rectangular box with line drawing characters
  477.  */
  478. void
  479. draw_box (WINDOW * win, int y, int x, int height, int width,
  480.       chtype box, chtype border)
  481. {
  482.     int i, j;
  483.  
  484.     wattrset (win, 0);
  485.     for (i = 0; i < height; i++) {
  486.     wmove (win, y + i, x);
  487.     for (j = 0; j < width; j++)
  488.         if (!i && !j)
  489.         waddch (win, border | ACS_ULCORNER);
  490.         else if (i == height - 1 && !j)
  491.         waddch (win, border | ACS_LLCORNER);
  492.         else if (!i && j == width - 1)
  493.         waddch (win, box | ACS_URCORNER);
  494.         else if (i == height - 1 && j == width - 1)
  495.         waddch (win, box | ACS_LRCORNER);
  496.         else if (!i)
  497.         waddch (win, border | ACS_HLINE);
  498.         else if (i == height - 1)
  499.         waddch (win, box | ACS_HLINE);
  500.         else if (!j)
  501.         waddch (win, border | ACS_VLINE);
  502.         else if (j == width - 1)
  503.         waddch (win, box | ACS_VLINE);
  504.         else
  505.         waddch (win, box | ' ');
  506.     }
  507. }
  508.  
  509. #ifdef HAVE_NCURSES
  510. /*
  511.  * Draw shadows along the right and bottom edge to give a more 3D look
  512.  * to the boxes
  513.  */
  514. void
  515. draw_shadow (WINDOW * win, int y, int x, int height, int width)
  516. {
  517.     int i;
  518.  
  519.     if (has_colors ()) {    /* Whether terminal supports color? */
  520.     wattrset (win, shadow_attr);
  521.     wmove (win, y + height, x + 2);
  522.     for (i = 0; i < width; i++)
  523.         waddch (win, winch (win) & A_CHARTEXT);
  524.     for (i = y + 1; i < y + height + 1; i++) {
  525.         wmove (win, i, x + width);
  526.         waddch (win, winch (win) & A_CHARTEXT);
  527.         waddch (win, winch (win) & A_CHARTEXT);
  528.     }
  529.     wnoutrefresh (win);
  530.     }
  531. }
  532. #endif
  533.  
  534. /*
  535.  * make_tmpfile()
  536.  */
  537. char *make_lock_filename(char *filename) {
  538.    char *file=(char *) malloc(30);
  539.    strcpy(file, filename);
  540.    if (mktemp(file) == NULL) {
  541.      endwin();
  542.      fprintf(stderr, "\nCan't make tempfile...\n");
  543.      return NULL;
  544.    }
  545.    return file;
  546. }
  547. /* End of make_tmpfile() */
  548.  
  549. /*
  550.  * Only a process at a time can call wrefresh()
  551.  */
  552.  
  553. /* called by all normal widget */
  554. void wrefresh_lock(WINDOW *win) {
  555.   wrefresh_lock_sub(win);
  556.   
  557.   if (exist_lock(lock_tailbg_refreshed))
  558.     remove_lock(lock_tailbg_refreshed);
  559.   
  560. }
  561.  
  562. /* If a tailboxbg was wrefreshed, wrefresh again the principal (normal) widget.
  563.  *
  564.  * The important thing here was to put cursor in the principal widget, 
  565.  * but with touchwin(win) the principal widget is also rewritten. This 
  566.  * is needed if a tailboxbg has overwritten this widget. 
  567.  */
  568. void ctl_idlemsg(WINDOW *win) {
  569.   if (exist_lock(lock_tailbg_refreshed))
  570.     wrefresh_lock(win);
  571.     
  572.   /* if a tailboxbg exited, quit */
  573.   if (exist_lock(lock_tailbg_exit)) { 
  574.     remove_lock(lock_tailbg_exit);
  575.     exiterr("");
  576.   }
  577. }
  578.  
  579. /* call by tailboxbg, the resident widget */
  580. void wrefresh_lock_tailbg(WINDOW *win) {
  581.   wrefresh_lock_sub(win);
  582.   create_lock(lock_tailbg_refreshed);
  583.   /* it's right also if more tailboxbg refresh */
  584.   /* with --no-kill flag the lock_tailbg_refreshed file
  585.      will not be removed :-/ :-| */
  586. }
  587.  
  588. /* private function, used by wrefresh_lock() and wrefresh_lock_tailbg() */
  589. void wrefresh_lock_sub(WINDOW *win) {
  590.   while_exist_lock(lock_refresh);
  591.   create_lock(lock_refresh);
  592.   wrefresh(win);
  593.   beeping();
  594.   wrefresh(win);
  595.   remove_lock(lock_refresh);
  596. }
  597. /* End of wrefresh functions */
  598.  
  599. /*
  600.  * To work with lock files, here are some functions
  601.  */
  602. int exist_lock(char *filename) {
  603.   FILE *fil;
  604.   if ((fil=fopen(filename, "r")) != NULL) {
  605.     fclose(fil);
  606.     return 1;
  607.   }
  608.   return 0;
  609. }
  610.  
  611. void while_exist_lock(char *filename) {
  612.   while (exist_lock(filename)) ;
  613. }
  614.  
  615. void create_lock(char *filename) {
  616.   FILE *fil=fopen(filename, "w");
  617.   fclose(fil);
  618. }
  619.  
  620. void remove_lock(char *filename) {
  621.   remove(filename);
  622. }
  623. /* End of functions to work with lock files */
  624.  
  625. /* killall_bg: kill all tailboxbg, if any */
  626. void killall_bg(void) {
  627.   int i;
  628.   for (i = 0; i < tailbg_lastpid; i++)
  629.     kill(tailbg_pids[i], 15);
  630. }
  631.  
  632. int is_nokill(int pid) { /* private func for quitall_bg() */
  633.   int i;
  634.   for (i = 0; i < tailbg_nokill_lastpid; i++)
  635.     if (tailbg_nokill_pids[i] == pid) return 1;
  636.   return 0;
  637. }
  638. /* quitall_bg: kill all tailboxbg without --no-kill flag */
  639. void quitall_bg(void) {
  640.   int i;
  641.   for (i = 0; i < tailbg_lastpid; i++)
  642.     if (!is_nokill(tailbg_pids[i]))
  643.       kill(tailbg_pids[i], 15);
  644. }
  645.  
  646. /* exiterr quit program killing all tailbg */
  647. void exiterr(char *str) {
  648.   if (screen_initialized)
  649.     endwin();
  650.  
  651.   fprintf(stderr, str);
  652.  
  653.   if (is_tailbg)    /* this is a child process */
  654.     create_lock(lock_tailbg_exit);
  655.   else 
  656.     killall_bg();
  657.     
  658.   exit(-1);
  659. }
  660.  
  661. void beeping() {
  662.   if (beep_signal) {
  663.     beep();
  664.     beep_signal = 0;
  665.   }
  666. }
  667.  
  668. void print_size(int height, int width) {
  669.   if (print_siz)
  670.     fprintf(stderr, "Size: %d, %d\n", height, width);
  671. }
  672.  
  673. void ctl_size(int height, int width) {
  674.   char *tempstr=(char *) malloc((size_t) MAX_LEN+1);
  675.   if (size_err)
  676.     if ((width > COLS) || (height > LINES)) {
  677.       sprintf(tempstr,"\nWindow too big. (Height, width) = (%d, %d). Max allowed (%d, %d).\n", height, width, LINES, COLS);
  678.       exiterr(tempstr);
  679.     } else if ((use_shadow) && ((width > SCOLS || height > SLINES))) {
  680.       sprintf(tempstr,"\nWindow+Shadow too big. (Height, width) = (%d, %d). Max allowed (%d, %d).\n", height, width, SLINES, SCOLS);
  681.       exiterr(tempstr);
  682.     }
  683. }
  684.  
  685. void tab_correct_str(char *prompt) {
  686.   char *ptr;
  687.   
  688.   if (!tab_correct) return;
  689.   
  690.   while ((ptr=strchr(prompt, TAB)) != NULL) {
  691.     *ptr=' ';
  692.     prompt=ptr;
  693.   }
  694. }
  695.  
  696. void calc_listh(int *height, int *list_height, int item_no) {
  697.     /* calculate new height and list_height */
  698.     int lines=SLINES-(begin_set ? begin_y : 0);
  699.     if (lines-(*height) > 0)
  700.       if (lines-(*height) > item_no)
  701.         *list_height=item_no;
  702.       else
  703.         *list_height=lines-(*height);
  704.     (*height)+=(*list_height);
  705. }
  706.  
  707. int calc_listw(int item_no, const char * const * items, int group) {
  708.     int n, i, len1=0, len2=0;
  709.     for (i=0; i<(item_no*group); i+=group) {
  710.       if ((n=strlen(items[i])) > len1) len1=n;
  711.       if ((n=strlen(items[i+1])) > len2) len2=n;
  712.     }
  713.     return len1+len2; 
  714. }
  715.  
  716. char *strclone(const char *cprompt) {
  717.     char *prompt=(char *) malloc(strlen(cprompt));
  718.     strcpy(prompt, cprompt);
  719.     return prompt;
  720. }
  721.